import React, {useState} from "react"
import {Editor, CircularView, LinearView, updateEditor} from "open-vector-editor"
import { tidyUpSequenceData } from "ve-sequence-utils";
import store from "../../store/index"
import headMenusJson from './utils/headmenus'
import rightClickMenusJson from './utils/rightclickmenus'
import pluginMethods from './utils/method'
import {initPropsJson} from './utils/setting'
import {ToolBarProps} from './utils/toolbar'
import './Editor.scss'

// 自定义组件方法
import myCustomDom from '../../utils/connectCustom'
import {compoentArr} from './components'

const flexStyle = {
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
}

function Vector(props) {
  const {
    windowAreactMethods,
    editorName,
    initData, // 外部传入数据（api请求返回）
    customProps, // 自定义的配置项props
    updateProps, // 插件更新时的props
    showCustomComponent, // 是否展示自定义组件
    componentID, // 自定义Tab组件ID
    previewSettingsProps, // 非预览模式下并且只读的 动态参数
    versionList, // 版本记录
    initDarkMode, // 皮肤 true:Dark
    moduleTag, // 元件数据类型
  } = props

  // 换肤
  const [darkMode, setDarkMode] = useState(initDarkMode)
  windowAreactMethods.setTheme = (mode) => {
    setDarkMode(mode)
  }

  // 定义获取panel的方法
  const [panelArr, setPanelArr] = useState([])
  windowAreactMethods.setPanels = (panel) => {
    setPanelArr(panel)
  }

  // 定义是否只读
  const [readOnly, setReadOnly] = useState(updateProps?.readOnly || previewSettingsProps?.readOnly || false)
  windowAreactMethods.setReadOnlyFn = (state) => {
    setReadOnly(state)
  }

  // 版本记录
  const [versionArr, setVersionArr] = useState(versionList)
  windowAreactMethods.setVersionArr = ({success, records}) => {
    if (success) {
      // console.info('React-> Update versionArr Success!')
      setVersionArr(records)
    } else {
      console.info('React-> Update versionArr Fail!')
    }
  }

  // 插件初始化的props
  const initProps = () => {
    if (previewSettingsProps && previewSettingsProps) {
      return previewSettingsProps
    } else {
      return {
        ...JSON.parse(initPropsJson),
        ToolBarProps: {
          ...ToolBarProps.call(this)
        }
      }
    }
  }

  // 是否全屏
  const [isFullscreen, setIsFullscreen] = useState(false)
  windowAreactMethods.setIsFullscreen = (state) => {
    setIsFullscreen(state)
  }

  // 自定义组件的扩展
  const [planMapComponent, setPlanMapComponent] = useState(null)
  React.useEffect(() => {
    let _panelMapJson = {}
    let currentComponent = (item) => ({
      editorName: editorName,
      customProps: customProps,
      sequenceData: initData,
      domComponent: item.component,
      darkMode: darkMode,
    })
    // 先将能匹配的id 的组件生成
    componentID.forEach(cId => {
      compoentArr.forEach(pItem => {
        if (pItem.id === cId) {
          _panelMapJson[cId] = myCustomDom({
            ...currentComponent(pItem)
          })
        }
      })
    })
    setPlanMapComponent({
      ..._panelMapJson
    })
  }, [componentID, editorName, customProps, initData, darkMode, panelArr, updateProps])

  // 根据依赖变化更新
  React.useEffect(() => {
    if (panelArr && panelArr.length) {
      updateProps.panelsShown = panelArr
    }

    // 换肤
    if (darkMode) {
      document.body.classList.contains('light') ? document.body.classList.replace('light', 'bp3-dark') : document.body.classList.add('bp3-dark')
    } else {
      document.body.classList.contains('bp3-dark') ? document.body.classList.replace('bp3-dark', 'light') : document.body.classList.add('light')
    }

    // 更新插件数据
    if (moduleTag === "Protein" || moduleTag === "protein") {
      updateEditor(store, editorName, {
        sequenceData: tidyUpSequenceData(initData, {
          convertAnnotationsFromAAIndices: true,
          isProtein: true,
          type: 'PROTEIN',
        }),
        ...updateProps,
      });
    } else if (moduleTag === "RNA") {
      updateEditor(store, editorName, {
        sequenceData: { ...initData, isRna: true },
        ...updateProps,
      });
    } else if (moduleTag === "Oligo") {
      updateEditor(store, editorName, {
        sequenceData: {
          sequence: initData.sequence,
          isOligo: true,
          circular: false
        },
        ...updateProps,
      });
    } else if (moduleTag === "mixedRnaAndDna") {
      updateEditor(store, editorName, {
        sequenceData: tidyUpSequenceData(
          {
            ...initData,
            sequence: "uuuu" + initData.sequence,
            isMixedRnaAndDna: true
          }, {}
        ),
        ...updateProps,
      });
    } else {
      updateEditor(store, editorName, {
        sequenceData: initData,
        ...updateProps,
      })
    }


    // OVE插件的state
    const OVESTATE = store.getState().VectorEditor[editorName]
    OVESTATE.readOnly = readOnly
    OVESTATE.annotationVisibility.parts = true

    if (customProps.withPreviewMode) {
      if (initData.circular) {
        window.AreactMethods.resetCircularViewSvgWidthAndHeight(document.documentElement.clientWidth, document.documentElement.clientHeight, 40)
      }
    }
  }, [darkMode, editorName, initData, updateProps, customProps.withPreviewMode, previewSettingsProps, readOnly, panelArr, moduleTag]);


  // 保存的回调函数
  const saveCallBackFn = (saveData, onSuccessCallback) => {
    if (window.Avue?.v_saveOveEditorAfterPost) {
      window.Avue.v_saveOveEditorAfterPost(saveData)
      // onSuccessCallback()
    } else {
      window.toastr.info("not found [v_saveOveEditorAfterPost], Save locally success!")
    }
  }

  const editProps = {
    editorName,
    isFullscreen,
    ...initProps(),
    ...customProps,
    ...pluginMethods.apply(this, 
      [customProps, isFullscreen, setIsFullscreen, headMenusJson, rightClickMenusJson, versionArr, saveCallBackFn]
    ),
  }

  return (
    <div style={flexStyle}>
      { customProps.withPreviewMode ? 
        (
          initData.circular ? 
          <CircularView {...editProps} /> : 
          <LinearView changeSize={true} {...editProps} />
        ) :  
        (
          showCustomComponent ? 
          <Editor style={{boxShadow: 'none'}} {...editProps} panelMap={planMapComponent} /> : 
          <Editor {...editProps} /> 
        )
      }
    </div>
  );
}

export default Vector;
